package rolemenu

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/container/gset"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/util/gconv"
	v1 "ruoyi-vue-pro-go/api/rolemenu/v1"
	"ruoyi-vue-pro-go/internal/dao"
	"ruoyi-vue-pro-go/internal/model/do"
	"ruoyi-vue-pro-go/internal/service"
)

type (
	sRoleMenu struct{}
)

func init() {
	service.RegisterRoleMenu(New())
}

func New() service.IRoleMenu {
	return &sRoleMenu{}
}

func (s *sRoleMenu) GetList(ctx context.Context, req *v1.GetListReq) (res *v1.GetListRes, err error) {
	res = &v1.GetListRes{}
	err = dao.SystemRoleMenu.Ctx(ctx).Scan(&res.List)
	return
}

func (s *sRoleMenu) GetListByRoleIds(ctx context.Context, req *v1.GetListByRoleIdsReq) (res *v1.GetListByRoleIdsRes, err error) {
	res = &v1.GetListByRoleIdsRes{}
	err = dao.SystemRoleMenu.Ctx(ctx).WhereIn("role_id", req.RoleIds).Where(do.SystemRoleMenu{}).Scan(&res.List)
	if err != nil {
		return nil, err
	}
	return res, nil
}

func (s *sRoleMenu) GetMenuIdListByRoleId(ctx context.Context, req *v1.GetMenuIdListByRoleIdReq) (res *v1.GetMenuIdListByRoleIdRes, err error) {
	res = &v1.GetMenuIdListByRoleIdRes{}
	var records []struct {
		MenuId int64 `json:"menu_id"`
	}
	err = dao.SystemRoleMenu.Ctx(ctx).Fields("menu_id").Where("role_id", req.RoleId).Scan(&records)
	if err != nil {
		return nil, err
	}
	for _, record := range records {
		res.MenuIds = append(res.MenuIds, record.MenuId)
	}
	return res, nil
}

func (s *sRoleMenu) AssignRoleMenu(ctx context.Context, req *v1.AssignRoleMenuReq) (res *v1.AssignRoleMenuRes, err error) {
	res = &v1.AssignRoleMenuRes{}
	reqMenuIds := req.MenuIds
	dbMenuIds, err := service.RoleMenu().GetMenuIdListByRoleId(ctx, &v1.GetMenuIdListByRoleIdReq{
		RoleId: req.RoleId,
	})
	if err != nil {
		fmt.Println("查询列表失败:", req.RoleId, err)
	}
	reqset := gset.NewFrom(reqMenuIds)
	dbset := gset.NewFrom(dbMenuIds.MenuIds)
	// 计算新增和删除的菜单编号
	addMenuIds := reqset.Diff(dbset).Slice()
	fmt.Println("add:", req.RoleId, addMenuIds)
	r := ghttp.RequestFromCtx(ctx)
	username := r.GetCtxVar("username").String()
	tenantId := gconv.Int64(r.Header.Get("Tenant-Id"))
	for _, menuId := range addMenuIds {
		_, err = dao.SystemRoleMenu.Ctx(ctx).Data(do.SystemRoleMenu{
			RoleId:   req.RoleId,
			MenuId:   menuId,
			Creator:  username,
			Updater:  username,
			TenantId: tenantId,
		}).OnConflict("role_id", "menu_id", "tenant_id").Save()
	}
	removeMenuIds := dbset.Diff(reqset).Slice()
	fmt.Println("remove:", req.RoleId, removeMenuIds)
	for _, menuId := range removeMenuIds {
		_, err = dao.SystemRoleMenu.Ctx(ctx).Where(do.SystemRoleMenu{
			RoleId: req.RoleId,
			MenuId: menuId,
		}).Delete()
	}
	return res, nil
}
